package ext.tianma.project2.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.rmi.RemoteException;
import java.sql.Blob;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;

import javax.sql.rowset.serial.SerialBlob;

import org.apache.commons.lang.StringUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import wt.content.ApplicationData;
import wt.doc.WTDocument;
import wt.fc.ObjectReference;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.PersistenceServerHelper;
import wt.fc.QueryResult;
import wt.fc.collections.WTArrayList;
import wt.fc.collections.WTCollection;
import wt.inf.container.ExchangeContainer;
import wt.inf.container.WTContainerHelper;
import wt.inf.team.ContainerTeamManagedState;
import wt.org.OrganizationServicesHelper;
import wt.org.WTGroup;
import wt.org.WTOrganization;
import wt.org.WTUser;
import wt.part.WTPart;
import wt.part.WTPartHelper;
import wt.part.WTPartMaster;
import wt.part.WTPartSubstituteLink;
import wt.part.WTPartUsageLink;
import wt.pds.StatementSpec;
import wt.projmgmt.admin.Project2;
import wt.query.ArrayExpression;
import wt.query.ClassAttribute;
import wt.query.OrderBy;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.session.SessionHelper;
import wt.session.SessionServerHelper;
import wt.type.ClientTypedUtility;
import wt.type.TypeDefinitionForeignKey;
import wt.type.TypeDefinitionReference;
import wt.type.Typed;
import wt.type.TypedUtility;
import wt.util.WTException;
import wt.util.WTProperties;
import wt.vc.VersionReference;
import wt.workflow.engine.WfProcess;

import com.ptc.core.lwc.server.LWCColumnAllocation;
import com.ptc.core.lwc.server.LWCFlexAttDefinition;
import com.ptc.core.lwc.server.LWCNormalizedObject;
import com.ptc.core.lwc.server.LWCTypeDefinition;
import com.ptc.core.meta.common.UpdateOperationIdentifier;
import com.ptc.projectmanagement.deliverable.PlanDeliverable;
import com.ptc.projectmanagement.plan.Plan;
import com.ptc.projectmanagement.plan.PlanActivity;
import com.ptc.projectmanagement.plan.Plannable;
import com.ptc.projectmanagement.plannable.PlannableHelper;

import ext.com.iba.IBAUtil;
import ext.com.org.OrgUtil;
import ext.tianma.bom.util.EnumerationUtil;
import ext.tianma.doc.SendOut.Interfaces.InterfaceService;
import ext.tianma.model.FormDataXml;
import ext.tianma.number.util.PartUtil;
import ext.tianma.project2.APQP.constants.APQPProjectConstant;
import ext.tianma.util.TMUtil;

public class ProjectUtil {
	
	private static final Logger logger = LoggerFactory.getLogger(ProjectUtil.class);
	
	public static final String FILENAME = "fileName";
	public static final String URLLINK = "urlLink";
	
	private static final String PARTCNANDENNAME = "partCNAndENName";//中英文名称
	private static final String PARTCNAME = "partCName";//中文名称
	private static final String PARTENAME = "partEName";//英文名称
	
	/**
	 * 获取群组
	 * @param groupName 群组名称
	 * @param isOrganization 是否组织下
	 * @return
	 * @author xucr
	 * @CreateDate 2020年9月27日
	 */
	public static WTGroup getWTGroup(String groupName, boolean isOrganization) {
		WTGroup g = null;
		try {
			if(isOrganization) {//组织下群组
				ExchangeContainer exchangecontainer = WTContainerHelper.service.getExchangeContainer();
				WTOrganization wtorganization = exchangecontainer.getOrganization();
				
				g = OrganizationServicesHelper.manager.getGroup(groupName, wtorganization);
			} else {//站点下群组
				g = OrganizationServicesHelper.manager.getGroup(groupName);
			}
		} catch (WTException e) {
			e.printStackTrace();
		}
		return g;
	}

	/**
	 * 判断用户是否在指定群组
	 * @param user 用户名称
	 * @param groupName
	 * @return
	 * @author xucr
	 * @CreateDate 2020年8月18日
	 */
	public static boolean isGroupUser(WTUser user, String groupName) {
		boolean flg = false;
		try {
			WTGroup g = getWTGroup(groupName, true);
		    
			if(null != g){
				flg = g.isMember(user);
			}
		} catch (WTException e) {
			e.printStackTrace();
		}
		return flg;
	}
	
	/**
	 * 查询用户集合
	 * @param userName 模糊匹配用户，支持：用户名、英文名称、中文名称
	 * @return
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年9月8日
	 */
	@SuppressWarnings({ "deprecation", "rawtypes" })
	public static List<WTUser> getUserList(String userName) throws WTException {
		/**
		 * 传递方式：
		 * 1、*userName*: 包含userName的用户
		 * 2、*userName : 以userName结束的用户
		 * 3、  userName*: 以userName开头的用户
		 * */
		List<WTUser> userList = new ArrayList<WTUser>();
		if(StringUtils.isNotEmpty(userName)) {
			WTUser user = null;
			Enumeration userList1 =  OrganizationServicesHelper.manager.findLikeUser("name", userName);
			while(userList1!=null && userList1.hasMoreElements()) {
				user = (WTUser)userList1.nextElement();
				//过滤掉离职组的人员  add by xuge_ning
				if(!OrgUtil.isMemberOfGroup("离职", user))
					userList.add(user);
			}
			Enumeration userList2 =  OrganizationServicesHelper.manager.findLikeUser("fullName", userName);
			while(userList2!=null && userList2.hasMoreElements()) {
				user = (WTUser)userList2.nextElement();
				if(!userList.contains(user) && !OrgUtil.isMemberOfGroup("离职", user))
					userList.add(user);
			}
		}
		return userList;
	}
	
	/**
	 * 返回APQP项目的中文状态
	 * @param project
	 * @return
	 * @author xucr
	 * @CreateDate 2020年9月15日
	 */
	public static String getProjectStateDisplay(Project2 project) {
		String display = "";
		if(null != project) {
			ContainerTeamManagedState state = project.getContainerTeamManagedInfo().getState();
			if(ContainerTeamManagedState.DEFINED.equals(state)) {
				display = "草稿";
			} else {
				display = state.getDisplay(Locale.CHINESE);
			}
		}
		return display;
	}
	
	/**
	 * 根据标准属性名称获取QueryName
	 * @param columnName 标准属性key
	 * @param type 对象类型
	 * @return
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年8月18日
	 */
	public static String getQueryName(String columnName, String type) throws WTException{
    	String queryName = "";
    	QuerySpec qs = new QuerySpec();
    	int index1 = qs.appendClassList(LWCColumnAllocation.class, true);
    	int index2 = qs.appendClassList(LWCFlexAttDefinition.class, false);
    	int index3 = qs.appendClassList(LWCTypeDefinition.class, false);
    	
    	qs.appendWhere(new SearchCondition(LWCColumnAllocation.class,"attributeDefReference.key.id",
    			LWCFlexAttDefinition.class,"thePersistInfo.theObjectIdentifier.id"), new int[]{index1,index2});
    	
    	qs.appendAnd();
    	qs.appendWhere(new SearchCondition(LWCFlexAttDefinition.class, LWCFlexAttDefinition.NAME, SearchCondition.EQUAL, columnName),new int[]{index2});
    	
    	qs.appendAnd();
    	qs.appendWhere(new SearchCondition(LWCColumnAllocation.class,"typeDefReference.key.id",
    			LWCTypeDefinition.class,"thePersistInfo.theObjectIdentifier.id"), new int[]{index1,index3});
    	
    	qs.appendAnd();
    	qs.appendWhere(new SearchCondition(LWCTypeDefinition.class, LWCTypeDefinition.NAME, SearchCondition.EQUAL, type),new int[]{index3});
    	
    	qs.appendOrderBy(new OrderBy(new ClassAttribute(LWCColumnAllocation.class,"thePersistInfo.theObjectIdentifier.id"),true),new int[]{index1});
    	
    	QueryResult qr = PersistenceHelper.manager.find((StatementSpec)qs);
    	
    	if(qr.hasMoreElements()){
    		Persistable[] persistable = (Persistable[]) qr.nextElement();
    		LWCColumnAllocation lwcColumnAllocation = (LWCColumnAllocation) persistable[0];
    		queryName = lwcColumnAllocation.getPhysicalName();
    	}
    	return queryName;
    }
	
	/**
	 * 获取枚举值列表
	 * @param enumerationTypeName
	 * @return
	 * @throws JSONException
	 * @author xucr
	 * @CreateDate 2020年8月18日
	 */
	public static JSONObject getEnumeration(String enumerationTypeName) throws JSONException {
		Map<String,String> maps = EnumerationUtil.getEnumerationValues(enumerationTypeName);
		JSONObject ob = new JSONObject();
		JSONArray array = new JSONArray();
		if(null != maps && maps.size() > 0) {
			ob.put("status", "success");
			ob.put("message", "查询成功!");
			
			JSONObject m = null;
			for(Entry<String, String> set: maps.entrySet() ) {
				m = new JSONObject();
				m.put("key", set.getKey());
				m.put("value", set.getValue());
				array.put(m);
			}
			ob.put("data", array);
		} else {
			ob.put("status", "false");
			ob.put("message", "未查到！");
		}
		return ob;
	}
	
	/**
	 * 获取群组成员
	 * @param groupName
	 * @throws WTException
	 * @author xucr
	 * @return 
	 * @throws JSONException 
	 * @CreateDate 2020年8月18日
	 */
	@SuppressWarnings("rawtypes")
	public static JSONObject getGroupMember(String groupName) throws WTException, JSONException {
		WTGroup g = getWTGroup(groupName, true);
		JSONArray array = new JSONArray();
		JSONObject result = new JSONObject();
		if(null != g) {
			Enumeration enumeration = g.members();
			
			JSONObject ob = null;
			while (enumeration.hasMoreElements()) {
				ob = new JSONObject();
				WTUser wtuser = (WTUser) enumeration.nextElement();
				ob.put("key", wtuser.getName());
				ob.put("value", wtuser.getFullName());
				array.put(ob);
			}
		}
		
		if(array.length() > 0) {
			result.put("status", "success");
			result.put("message", "查询成功!");
			result.put("data", array);
		} else {
			result.put("status", "false");
			result.put("message", "未查到！");
		}
		return result;
	}
	
	/**
	 * 得到所有活动
	 * @param plan
	 * @return
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年8月21日
	 */
	public static List<PlanActivity> getAllActivity(Plan plan)throws WTException {
		List<PlanActivity> activities = new ArrayList<PlanActivity>();
		WTCollection planables = PlannableHelper.service.getAllPlannables(plan,false);
		Iterator iter = planables.iterator();
		ObjectReference objRef = null;
		PlanActivity activity = null;
		while (iter.hasNext()) {
			objRef = (ObjectReference) iter.next();
			activity = (PlanActivity) objRef.getObject();
			if(0 != activity.getLineNumber()) {
				activities.add((PlanActivity) objRef.getObject());
			}
		}
		return activities;
	}
	
	/**
	 * 得到任务的直接子项
	 * @param plannable
	 * @return
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年8月21日
	 */
	public static List<PlanActivity> getAllChildren(Plannable plannable)throws WTException {
		
		List<PlanActivity> activities = new ArrayList<PlanActivity>();
		if(null == plannable) {
			return activities;
		}
		QuerySpec qs = new QuerySpec(PlanActivity.class);
		
		SearchCondition sc1 = new SearchCondition(PlanActivity.class, "parentReference.key.id", 
				SearchCondition.EQUAL, plannable.getPersistInfo().getObjectIdentifier().getId());
		qs.appendWhere(sc1, new int[] { 0 });
		
		SearchCondition sc2 = new SearchCondition(PlanActivity.class, PlanActivity.LINE_NUMBER, 
				SearchCondition.NOT_EQUAL, 0);
		qs.appendAnd();
		qs.appendWhere(sc2, new int[] { 0 });
		
		SearchCondition sc3 = new SearchCondition(PlanActivity.class,"thePersistInfo.markForDelete", SearchCondition.EQUAL, 0L);
		qs.appendAnd();
	    qs.appendWhere(sc3, new int [] {0});
		
	    logger.info("getAllChildren  qs>>>>" + qs.toString());
		QueryResult qr = PersistenceHelper.manager.find(qs);
		PlanActivity activity = null;
		while(qr.hasMoreElements()) {
			activity = (PlanActivity) qr.nextElement();
			activities.add(activity);
		}
		return activities;
	}
	
	/**
	 * 返回表格数据
	 * @param array 数据源
	 * @param total 数据总数
	 * @return
	 * @throws JSONException
	 * @author xucr
	 * @CreateDate 2020年8月24日
	 */
	public static JSONObject respInfo(JSONArray array, int total) throws JSONException {
		JSONObject result = new JSONObject();
		if(array.length() > 0) {
	    	result.put("count", total);
	    	result.put("data", array);
	    	result.put("code", "0");
			result.put("msg", "");
		} else {
			result.put("count", 0);
			result.put("data", new JSONArray());
			result.put("code", "1");
			result.put("msg", "您查询的数据不存在!");
		}
		return result;
	}
	
	/**
	 * 得到BOM所有指定类型的子项
	 * @param part 顶层
	 * @param partSoftType 类型，如 原材料：cn.tianma.RawMaterial
	 * @param list 返回结果集
	 * @author xucr
	 * @CreateDate 2020年8月21日
	 */
	public static void getChildPart(WTPart part, String partSoftType, List<WTPart> list) {
		try {
			QueryResult qs = WTPartHelper.service.getUsesWTPartMasters(part);
			while (qs.hasMoreElements()) {
				WTPartUsageLink link = (WTPartUsageLink) qs.nextElement();
				WTPartMaster master = (WTPartMaster) link.getRoleBObject();
//				WTPart childpart = BOMHelp.getPart(master.getNumber(), "", part.getViewName());
				WTPart childpart = PartUtil.getWTPartByNumber(master.getNumber());
				if(null != childpart) {
					//只查询指定类型部件
					String typeName = TypedUtility.getTypeIdentifier(childpart).getTypename();
					if (!list.contains(childpart) && typeName.indexOf(partSoftType) > -1) {
						
						//特定替换部件
						WTArrayList c = (WTArrayList)WTPartHelper.service.getSubstituteLinksAnyAssembly(
								(WTPartMaster) childpart.getMasterReference().getObject());
						if(null != c && c.size() > 0) {
							ObjectReference obj = null;
							for(int j = 0 ; j < c.size(); j++) {
								obj =  (ObjectReference) c.get(0);
								WTPartSubstituteLink ul = (WTPartSubstituteLink) obj.getObject();
								WTPartMaster wm = (WTPartMaster) ul.getRoleBObject();
//								WTPart linkPart = BOMHelp.getPart(wm.getNumber(), "", childpart.getViewName());
								WTPart linkPart = PartUtil.getWTPartByNumber(wm.getNumber());
								
								if(!list.contains(linkPart) && null != linkPart)
									list.add(linkPart);
							}
						}
						list.add(childpart);
					}
					if (childpart != null) {
						getChildPart(childpart, partSoftType, list);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 查询交付物主题集合
	 * @param activity
	 * @param isSubject 是否含主题
	 * @return
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年8月26日
	 */
	public static List<PlanDeliverable> getDeliverableWithSubjectByActivity(PlanActivity activity, boolean isSubject) throws WTException {
		SessionServerHelper.manager.setAccessEnforced(false);
		List<PlanDeliverable> deliverables = new ArrayList<PlanDeliverable>();
		WTCollection localWTCollection = PlannableHelper.service.getDeliverables(activity);
		if (null != localWTCollection && localWTCollection.size() > 0) {
			Iterator localIterator = localWTCollection.persistableIterator(PlanDeliverable.class, true);
			while (localIterator.hasNext()) {
				PlanDeliverable localPlanDeliverable = (PlanDeliverable) localIterator.next();
				if(isSubject) {
					Persistable p = localPlanDeliverable.getSubject().getObject();
					if (p != null)
						deliverables.add(localPlanDeliverable);
				} else {
					deliverables.add(localPlanDeliverable);
				}
			}
		}
		return deliverables;
	}
	
	/**
	 * 获取交付物的文档
	 * @param deliver
	 * @param isHTMLTreaty
	 * @param isLabel
	 * @return
	 * @throws IOException
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年10月21日
	 */
	public static WTDocument getDeliveryDOc (PlanDeliverable deliver) throws IOException, WTException{
		VersionReference vr = deliver.getSubject();
		WTDocument doc = null;
		if(null != vr) {
			Persistable p = deliver.getSubject().getObject();
			if(p instanceof WTDocument) {
				doc = (WTDocument) p;
			}
		}
		return doc;
	}
	
//	/**
//	 * 构造交付物链接
//	 * @param deliver
//	 * @param isHTMLTreaty 是否带http请求
//	 * @param isLabel 是否带a标签
//	 * @return
//	 * @throws IOException
//	 * @author xucr
//	 * @throws WTException 
//	 * @CreateDate 2020年8月26日
//	 */
//	public static Map<String, String> getDeliveryUrlLink (PlanDeliverable deliver , boolean isHTMLTreaty, boolean isLabel) throws IOException, WTException{
//		Map<String, String> result = new HashMap<String, String>();
//		String urlLink = "";
//		VersionReference vr = deliver.getSubject();
//		if(null != vr) {
//			Persistable p = deliver.getSubject().getObject();
//			String pOid = "";
//			String applicationData = "";
//			String fileName = "";
//			if(p instanceof WTDocument) {
//				pOid = p.toString();
//				WTDocument doc = (WTDocument) p;
//				ApplicationData appdata = InterfaceService.getPrimaryContent(doc);
//				if(null != appdata) {
//					applicationData = TMUtil.obj2Oid(appdata);
//					fileName = appdata.getFileName();
//					result.put(FILENAME, fileName);
//				}
//				
//				StringBuffer url = new StringBuffer();
//				if(isHTMLTreaty){
//					WTProperties pro = WTProperties.getLocalProperties();
//					String localProperties = pro.getProperty("java.rmi.server.hostname");
////					//文档链接
////					url.append("http://").append(localProperties)
////						.append("/Windchill/app/#ptc1/tcomp/infoPage?oid=").append(pOid).append("&u8=1");
//					
//					//下载链接
//					url.append("http://").append(localProperties)
//					.append("/Windchill/servlet/AttachmentsDownloadDirectionServlet?oid=").append(pOid)
//					.append("&oid=").append(applicationData)
//					.append("&role=PRIMARY");
//				}else{
////					//文档链接
////					url.append("/Windchill/app/#ptc1/tcomp/infoPage?oid=").append(pOid).append("&u8=1");
//					
//					url.append("/Windchill/servlet/AttachmentsDownloadDirectionServlet?oid=").append(pOid)
//					.append("&oid=").append(applicationData)
//					.append("&role=PRIMARY");
//				}
//				
//				if(isLabel) {
//					urlLink = "<a title='" + fileName + "' href='" + url + "' target='_blank'>" + fileName + "</a>";
//				} else {
//					urlLink = url.toString();
//				}
//				result.put(URLLINK, urlLink);
//			}
//		}
//		return result;
//	}
	
	/**
	 * 构造交付物链接
	 * @param deliver
	 * @param isHTMLTreaty 是否带http请求
	 * @param isLabel 是否带a标签
	 * @return
	 * @throws IOException
	 * @author xucr
	 * @throws WTException 
	 * @CreateDate 2020年8月26日
	 */
	public static Map<String, String> getDeliveryUrlLink (PlanDeliverable deliver , boolean isHTMLTreaty, boolean isLabel) throws IOException, WTException{
		Map<String, String> result = new HashMap<String, String>();
		String urlLink = "";
		String applicationData = "";
		String fileName = "";
		WTDocument doc = getDeliveryDOc(deliver);
		if(null != doc) {
			String pOid = TMUtil.obj2Oid(doc);
			ApplicationData appdata = InterfaceService.getPrimaryContent(doc);
			if(null != appdata) {
				applicationData = TMUtil.obj2Oid(appdata);
				fileName = appdata.getFileName();
				result.put(FILENAME, fileName);
			}
			
			StringBuffer url = new StringBuffer();
			if(isHTMLTreaty){
				WTProperties pro = WTProperties.getLocalProperties();
				String localProperties = pro.getProperty("java.rmi.server.hostname");
//				//文档链接
//				url.append("http://").append(localProperties)
//					.append("/Windchill/app/#ptc1/tcomp/infoPage?oid=").append(pOid).append("&u8=1");
				
				//下载链接
				url.append("http://").append(localProperties)
				.append("/Windchill/servlet/AttachmentsDownloadDirectionServlet?oid=").append(pOid)
				.append("&oid=").append(applicationData)
				.append("&role=PRIMARY");
			}else{
//				//文档链接
//				url.append("/Windchill/app/#ptc1/tcomp/infoPage?oid=").append(pOid).append("&u8=1");
				
				url.append("/Windchill/servlet/AttachmentsDownloadDirectionServlet?oid=").append(pOid)
				.append("&oid=").append(applicationData)
				.append("&role=PRIMARY");
			}
			
			if(isLabel) {
				urlLink = "<a title='" + fileName + "' href='" + url + "' target='_blank'>" + fileName + "</a>";
			} else {
				urlLink = url.toString();
			}
			result.put(URLLINK, urlLink);
		}
		return result;
	}
	
	/**
	 * 按照条件搜索APQP
	 * @param params
	 * @author xucr
	 * @throws JSONException 
	 * @throws WTException 
	 * @throws RemoteException 
	 * @CreateDate 2020年8月24日
	 */
	public static QuerySpec queryAPQPsByParams(JSONObject params, String projectType) throws JSONException, WTException, RemoteException {
		QuerySpec qs = new QuerySpec(Project2.class);
	    qs.setAdvancedQueryEnabled(true);
	    
	    Long markDelete = (long) 0;
	    SearchCondition sc1 = new SearchCondition(Project2.class,"thePersistInfo.markForDelete", SearchCondition.EQUAL, markDelete);
	    qs.appendWhere(sc1, new int [] {0});
	    
	    if(StringUtils.isNotEmpty(projectType)) {
	    	//仅查询APQP项目
			TypeDefinitionReference clientType = ClientTypedUtility.getTypeDefinitionReference(projectType);
			SearchCondition sc = new SearchCondition(Project2.class,
					Typed.TYPE_DEFINITION_REFERENCE + "." + TypeDefinitionReference.KEY + "." + TypeDefinitionForeignKey.BRANCH_ID, 
					SearchCondition.EQUAL, clientType.getKey().getBranchId());
			qs.appendAnd();
			qs.appendWhere(sc, new int[] { 0 });
	    }
	    
	    if(null != params) {
		    //productType:”产品类型”,
	    	if(params.has("productType") && StringUtils.isNotEmpty(params.getString("productType"))) {
	    		String productType = params.getString("productType");
	    		String productTypeQueryName = ProjectUtil.getQueryName("productType", APQPProjectConstant.APQP_PROJECT);
	    		SearchCondition sc = new SearchCondition(Project2.class,productTypeQueryName, SearchCondition.LIKE, "%" + productType + "%");
	    		qs.appendAnd();
	    		qs.appendWhere(sc, new int [] {0});
	    	}
	    	
		    //modelName:”机型名称”,
	    	if(params.has("modelName") && StringUtils.isNotEmpty(params.getString("modelName"))) {
	    		String modelName = params.getString("modelName");
	    		String modelNameQueryName = ProjectUtil.getQueryName("modelName", APQPProjectConstant.APQP_PROJECT);
	    		SearchCondition sc = new SearchCondition(Project2.class,modelNameQueryName, SearchCondition.LIKE, "%" + modelName + "%");
	    		qs.appendAnd();
	    		qs.appendWhere(sc, new int [] {0});
	    	}
	    	
		    //customerName:”客户名称”,
	    	if(params.has("customerName") && StringUtils.isNotEmpty(params.getString("customerName"))) {
	    		String customerName = params.getString("customerName");
	    		String customerNameQueryName = ProjectUtil.getQueryName("customerName", APQPProjectConstant.APQP_PROJECT);
	    		SearchCondition sc = new SearchCondition(Project2.class,customerNameQueryName, SearchCondition.LIKE, "%" + customerName + "%");
	    		qs.appendAnd();
	    		qs.appendWhere(sc, new int [] {0});
	    	}
	    	
		    //pm：”PM”,
	    	if(params.has("pm") && StringUtils.isNotEmpty(params.getString("pm"))) {
	    		String pm = params.getString("pm");
	    		String pmQueryName = ProjectUtil.getQueryName("pm", APQPProjectConstant.APQP_PROJECT);
	    		SearchCondition sc = new SearchCondition(Project2.class,pmQueryName, SearchCondition.LIKE, "%" + pm + "%");
	    		qs.appendAnd();
	    		qs.appendWhere(sc, new int [] {0});
	    	}
	    	
		    //state:”当前状态”
	    	if(params.has("status") && StringUtils.isNotEmpty(params.getString("status"))) {
	    		String status = params.getString("status");
	    		SearchCondition sc = new SearchCondition(Project2.class,"containerTeamManagedInfo.state", SearchCondition.EQUAL, status);
	    		qs.appendAnd();
	    		qs.appendWhere(sc, new int [] {0});
	    	}
	    	
		    //createDate: “创建时间Form-to”
	    	if(params.has("arrangeDate") && StringUtils.isNotEmpty(params.getString("arrangeDate"))) {
	    		String dateForm = params.getString("arrangeDate");
	    		if(!"null".equals(dateForm)) {
	    			JSONArray array = new JSONArray(dateForm);
		    		Date startDate = TMUtil.getDate(array.getString(0), "yyyy-MM-dd");
		    		Date endDate = TMUtil.getDate(array.getString(1), "yyyy-MM-dd");
		    		
		    		SearchCondition sc = new SearchCondition(
		    				Project2.class,Project2.CREATE_TIMESTAMP, SearchCondition.GREATER_THAN_OR_EQUAL, new Timestamp(startDate.getTime()));
		    		qs.appendAnd();
		    		qs.appendWhere(sc, new int [] {0});
		    		
		    		SearchCondition sc2 = new SearchCondition(
		    				Project2.class,Project2.CREATE_TIMESTAMP, SearchCondition.LESS_THAN_OR_EQUAL, new Timestamp(endDate.getTime()));
		    		qs.appendAnd();
		    		qs.appendWhere(sc2, new int [] {0});
	    		}
	    	}
	    	
	    	//id集合
	    	if(params.has("ids") && StringUtils.isNotEmpty(params.getString("ids"))) {
	    		String [] ids = params.getString("ids").split(APQPProjectConstant.SPLITVALUE);
	    		Long [] _ids = new Long [ids.length];
	    		for(int i = 0 ; i < ids.length; i++) {
	    			_ids[i] = Long.valueOf(ids[i].replace(APQPProjectConstant.PROJECTOR, ""));
	    		}
	    		SearchCondition sc = new SearchCondition(new ClassAttribute(
	    				Project2.class, "thePersistInfo.theObjectIdentifier.id"), SearchCondition.IN, new ArrayExpression(_ids));
	    		qs.appendAnd();
	    		qs.appendWhere(sc, new int [] {0});
	    	}
	    	
	    	//追加活动搜索条件
	    	addPlanActivityCondition(qs, params);
	    }
	    qs.appendOrderBy(new OrderBy(new ClassAttribute(Project2.class,Project2.CREATE_TIMESTAMP),true),new int[]{0});
	    logger.info("queryAPQPsByParams sql >>>>" + qs.toString());
	    return qs;
	}
	
	/**
	 * 搜索项目时，追加活动上的条件
	 * @param qs
	 * @param params
	 * @throws JSONException
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年9月25日
	 */
	private static void addPlanActivityCondition(QuerySpec qs, JSONObject params) throws JSONException, WTException {
		int p2 = qs.getFromClause().getPosition(Project2.class);
		int p = qs.appendClassList(PlanActivity.class, false);
		if(qs.getConditionCount() > 0) {
			qs.appendAnd();
		}
		SearchCondition sc1 = new SearchCondition(
				PlanActivity.class, "containerReference.key.id", Project2.class, "thePersistInfo.theObjectIdentifier.id");
        qs.appendWhere(sc1, new int[]{p, p2});
        
        /**
         * 以项目为维度搜索时，返回情况：项目：活动=1:1
         * 因为这里有按照活动条件搜索，而这些值在L1计划都有，因此将L1作为固定条件，保证project与planactivity以1:1展示
         * 1、有活动作为条件时，加上固定：hierarchy=L1
         * 2、无活动作为条件时，加上固定：lineNumber=0
		*/
        if((params.has("materialCategory") && StringUtils.isNotEmpty(params.getString("materialCategory")))
				|| (params.has("supplier") && StringUtils.isNotEmpty(params.getString("supplier")))) {
        	params.put("hierarchy", "L1");
		} else {
			params.put(PlanActivity.LINE_NUMBER, 0);
		}
        
		queryPlanActivityCondition(qs, params);
	}
	
	/**
	 * add搜索活动的条件
	 * @param qs
	 * @param params
	 * @throws JSONException
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年9月25日
	 */
	private static void queryPlanActivityCondition(QuerySpec qs, JSONObject params) throws JSONException, WTException {
		int pa = qs.getFromClause().getPosition(PlanActivity.class);
		//lineNumber
		if (params.has(PlanActivity.LINE_NUMBER) && StringUtils.isNotEmpty(PlanActivity.LINE_NUMBER)) {
			int lineNumber = params.getInt(PlanActivity.LINE_NUMBER);
			SearchCondition sc2 = new SearchCondition(PlanActivity.class,PlanActivity.LINE_NUMBER, SearchCondition.EQUAL, lineNumber);
			qs.appendAnd();
			qs.appendWhere(sc2, new int[]{pa});
		}
		
		//活动状态
        if (params.has("planStates") && StringUtils.isNotEmpty(params.getString("planStates"))) {
        	String [] states = params.getString("planStates").split(",");
            SearchCondition sc5 = new SearchCondition(
            		new ClassAttribute(PlanActivity.class, PlanActivity.PLANNABLE_STATE), SearchCondition.IN, new ArrayExpression(states));
            qs.appendAnd();
            qs.appendWhere(sc5, new int[]{pa});
        }

        //计划开始日期
        if (params.has("startDate") && StringUtils.isNotEmpty(params.getString("startDate"))) {
        	String date = params.getString("startDate");
        	Timestamp t = TMUtil.getTimestamp(date);
        	SearchCondition sc6 = new SearchCondition(PlanActivity.class, PlanActivity.START_DATE, SearchCondition.LESS_THAN_OR_EQUAL, t);
            qs.appendAnd();
            qs.appendWhere(sc6, new int[]{pa});
        }

        //层级
        if (params.has("hierarchy") && StringUtils.isNotEmpty(params.getString("hierarchy"))) {
        	String hierarchy = params.getString("hierarchy");
            String hierarchyQueryName = ProjectUtil.getQueryName("hierarchy", APQPProjectConstant.APQP_PLANACTIVITY);
            SearchCondition sc7 = new SearchCondition(PlanActivity.class, hierarchyQueryName,  SearchCondition.EQUAL, hierarchy);
            qs.appendAnd();
            qs.appendWhere(sc7, new int[]{pa});
        }
        
        //是否达标
        if (params.has("isStandard") && StringUtils.isNotEmpty(params.getString("isStandard"))) {
        	String isStandard = params.getString("isStandard");
            String hierarchyQueryName = ProjectUtil.getQueryName("isStandard", APQPProjectConstant.APQP_PLANACTIVITY);
            SearchCondition sc8 = new SearchCondition(PlanActivity.class, hierarchyQueryName,  SearchCondition.EQUAL, isStandard);
            qs.appendAnd();
            qs.appendWhere(sc8, new int[]{pa});
        }
        
        //是否已上载
        if (params.has("isUpload") && StringUtils.isNotEmpty(params.getString("isUpload"))) {
        	String isUpload = params.getString("isUpload");
            String hierarchyQueryName = ProjectUtil.getQueryName("isUpload", APQPProjectConstant.APQP_PLANACTIVITY);
            SearchCondition sc9 = new SearchCondition(PlanActivity.class, hierarchyQueryName,  SearchCondition.EQUAL, isUpload);
            qs.appendAnd();
            qs.appendWhere(sc9, new int[]{pa});
        }
        
        //Supplier
        if (params.has("supplier") && StringUtils.isNotEmpty(params.getString("supplier"))) {
        	String supplier = params.getString("supplier");
            String supplierQueryName = ProjectUtil.getQueryName("supplier", APQPProjectConstant.APQP_PLANACTIVITY);
            SearchCondition sc7 = new SearchCondition(PlanActivity.class, supplierQueryName, SearchCondition.LIKE, "%" + supplier + "%");
            qs.appendAnd();
            qs.appendWhere(sc7, new int[]{pa});
        }
        
        //物料类别
        if (params.has("materialCategory") && StringUtils.isNotEmpty(params.getString("materialCategory"))) {
        	String materialCategory = params.getString("materialCategory");
            String materialCategoryQueryName = ProjectUtil.getQueryName("materialCategory", APQPProjectConstant.APQP_PLANACTIVITY);
            SearchCondition sc7 = new SearchCondition(PlanActivity.class, materialCategoryQueryName, SearchCondition.LIKE, "%" + materialCategory + "%");
            qs.appendAnd();
            qs.appendWhere(sc7, new int[]{pa});
        }
        
        //P/N : 在同步BOM时，若有删除时，根据传递的所有PN号筛选
        if (params.has("pn") && StringUtils.isNotEmpty(params.getString("pn"))) {
        	String pn = params.getString("pn");
            String pnQueryName = ProjectUtil.getQueryName("pn", APQPProjectConstant.APQP_PLANACTIVITY);
            SearchCondition sc8 = new SearchCondition(
            		new ClassAttribute(PlanActivity.class, pnQueryName), SearchCondition.IN, new ArrayExpression(pn.split(",")));
            qs.appendAnd();
            qs.appendWhere(sc8, new int[]{pa});
        }
	}
	
	/**
	 * 根据条件查询活动
	 * @param project
	 * @param params
	 * @author xucr
	 * @throws JSONException 
	 * @throws WTException 
	 * @CreateDate 2020年8月27日
	 */
	public static QuerySpec queryPlanActivityByParams(Project2 project, JSONObject params) throws JSONException, WTException {
		QuerySpec qs = new QuerySpec();
		int pa = qs.appendClassList(PlanActivity.class, true);
		int p2 = qs.appendClassList(Project2.class, false);
	    qs.setAdvancedQueryEnabled(true);
	    
	    SearchCondition sc1 = new SearchCondition(PlanActivity.class,PlanActivity.LINE_NUMBER, SearchCondition.NOT_EQUAL, 0);
	    qs.appendWhere(sc1, new int [] {pa});

        //p2.ida2a2 = pa.ida3Containerreference
        SearchCondition sc2 = new SearchCondition(
        		PlanActivity.class, "containerReference.key.id", Project2.class, "thePersistInfo.theObjectIdentifier.id");
        qs.appendAnd();
        qs.appendWhere(sc2, new int[]{pa, p2});
        
        //当传入项目时，则查询指定项目
        if(null != project) {
        	Long projectId = project.getPersistInfo().getObjectIdentifier().getId();
        	SearchCondition sc3 = new SearchCondition(
            		PlanActivity.class, "containerReference.key.id", SearchCondition.EQUAL, projectId);
        	qs.appendAnd();
            qs.appendWhere(sc3, new int[]{pa});
        }

        //项目状态
        if (params.has("projectState") && StringUtils.isNotEmpty(params.getString("projectState"))) {
        	String [] states = params.getString("projectState").split(",");
            SearchCondition sc4 = new SearchCondition(
            		new ClassAttribute(Project2.class, "containerTeamManagedInfo.state"), SearchCondition.IN, new ArrayExpression(states));
            qs.appendAnd();
            qs.appendWhere(sc4, new int[]{p2});
        }
        
        queryPlanActivityCondition(qs, params);
        logger.info("queryPlanActivityByParams sql >>>>" + qs.toString());
        return qs;
	}
	
	/**
	 * 获取物料的中英文名称
	 * @param wtpart
	 * @return
	 * @author xucr
	 * @CreateDate 2020年10月16日
	 */
	public static String getPartCNAndENName(WTPart wtpart) {
		String partCNAndENName = "";
		try {
			if(null != wtpart) {
				partCNAndENName = (String) IBAUtil.getIBAValue(wtpart, PARTCNANDENNAME);
				
				if(StringUtils.isEmpty(partCNAndENName)) {
					String partCname = (String) IBAUtil.getIBAValue(wtpart, PARTCNAME);
					String partEname = (String) IBAUtil.getIBAValue(wtpart, PARTENAME);
					
					partCNAndENName = partEname + " -- " + partCname;
				}
			}
		} catch (RemoteException | WTException e) {
			e.printStackTrace();
		}
		return partCNAndENName;
	}
	
	public static QuerySpec queryFormDataXml(WfProcess wfprocess, Project2 project, String processState) throws WTException {
		QuerySpec qs = new QuerySpec(FormDataXml.class);
	    qs.setAdvancedQueryEnabled(true);
	    
	    boolean isAnd = false;
	    if(null != wfprocess) {
	    	Long wfId = wfprocess.getPersistInfo().getObjectIdentifier().getId();
	 	    SearchCondition sc = new SearchCondition(FormDataXml.class, "process.key.id",  SearchCondition.EQUAL, wfId);
	 	    qs.appendWhere(sc, new int [] {0});
	 	   isAnd = true;
	    }
	    
	    if(null != project) {
	    	Long projectId = project.getPersistInfo().getObjectIdentifier().getId();
	 	    SearchCondition sc = new SearchCondition(FormDataXml.class, "persistable.key.id",  SearchCondition.EQUAL, projectId);
	 	    if(isAnd) {
	 	    	qs.appendAnd();
	 	    }
	 	    qs.appendWhere(sc, new int [] {0});
	 	    isAnd = true;
	    }
	    
	    //与project适用，通过process最多查询一条，而通过process可能查出多条
	    if(StringUtils.isNotEmpty(processState)) {
	    	SearchCondition sc = new SearchCondition(FormDataXml.class, FormDataXml.STATUS,  SearchCondition.EQUAL, processState);
	    	if(isAnd) {
	 	    	qs.appendAnd();
	 	    }
	 	    qs.appendWhere(sc, new int [] {0});
	    }
	    qs.appendOrderBy(new OrderBy(new ClassAttribute(FormDataXml.class,FormDataXml.CREATE_TIMESTAMP),true),new int[]{0});
	    logger.info("queryFormDataXml sql >>>" + qs.toString());
	    return qs;
	}
	
	public static Blob str2Blob(String str) {
		Blob blob = null;
		try  {
			ByteArrayOutputStream out = new  ByteArrayOutputStream();
            ObjectOutputStream outputStream = new  ObjectOutputStream(out);
            outputStream.writeObject(str);
            byte [] bytes  =  out.toByteArray();
            outputStream.close();
            blob= new SerialBlob(bytes);
        }  catch  (Exception e) {
            e.printStackTrace();
        }
		return blob;
	}
	
	/**
	 * BLOB转成list
	 * @param blob
	 * @return
	 * @throws IOException
	 */
	public static String blob2str(Blob blob){
		String str = "";
		try  {
            ObjectInputStream in  = new ObjectInputStream(blob.getBinaryStream());
            str = (String) in.readObject();
            in.close();   
        }  catch  (Exception e) {
            e.printStackTrace();
        }
		return str;
	}
	
//	public static WTPart getPart(String num, String ver, String viewName, String softType) throws Exception {
//		if (viewName.equals(""))
//			viewName = "Design";
//		if (num == null || num.equals("") || num.trim().equals(""))
//			return null;
//		View view = ViewHelper.service.getView(viewName);
//		WTPart part = null;
//		QuerySpec qs = new QuerySpec(WTPart.class);
//		SearchCondition sc = new SearchCondition(WTPart.class, WTPart.NUMBER, SearchCondition.EQUAL, num);
//		qs.appendWhere(sc, new int[] { 0 });
//		sc = new SearchCondition(WTPart.class, "view.key.id", SearchCondition.EQUAL,
//				view.getPersistInfo().getObjectIdentifier().getId());
//		qs.appendAnd();
//		qs.appendWhere(sc, new int[] { 0 });
//		if (!ver.equals("")) {
//			qs.appendAnd();
//			qs.appendWhere(new SearchCondition(new KeywordExpression("A0.versionida2versioninfo"),
//					SearchCondition.EQUAL, new KeywordExpression("'" + ver + "'")));
//		}
//		qs.appendAnd();
//		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.latestiterationinfo"), SearchCondition.EQUAL,
//				new KeywordExpression("1")), new int[] { 0 } );
//		
//		//仅查询指定类型
//		if(StringUtils.isNotEmpty(softType)) {
//			TypeDefinitionReference clientType = ClientTypedUtility.getTypeDefinitionReference(softType);
//			SearchCondition sc1 = new SearchCondition(WTPart.class,
//					Typed.TYPE_DEFINITION_REFERENCE + "." + TypeDefinitionReference.KEY + "." + TypeDefinitionForeignKey.BRANCH_ID, 
//					SearchCondition.EQUAL, clientType.getKey().getBranchId());
//			qs.appendAnd();
//			qs.appendWhere(sc1, new int[] { 0 });
//		}
//
//		qs.appendOrderBy(WTPart.class, "thePersistInfo.createStamp", true);
//		QueryResult qr = PersistenceHelper.manager.find(qs);
//		while (qr.hasMoreElements()) {
//			part = (WTPart) qr.nextElement();
//			OneOffVersionInfo one = part.getOneOffVersionInfo();
//			OneOffVersionIdentifier id = one.getIdentifier();
//			String valueOneOff = id.getValue();
//			if (valueOneOff == null)
//				return part;
//		}
//		return part;
//	}
	
	/**
	 * 保存标准属性
	 * @param persistable
	 * @param attrMap
	 * @param isOOTBValidate
	 * @return
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年8月20日
	 */
	public Persistable update(Persistable persistable, Map<String,Object> attrMap, boolean isOOTBValidate) throws WTException{
		LWCNormalizedObject obj = new LWCNormalizedObject(persistable,null,SessionHelper.getLocale(),new UpdateOperationIdentifier());
		
		persistable = setAttr(attrMap, obj);
		persistable = updatePersistable(persistable, isOOTBValidate);
		
		return persistable;
	}
	
	public Persistable setAttr(Map<String, Object> attrMap, LWCNormalizedObject obj) throws WTException {
	    obj.load(attrMap.keySet());//防止更新IBA实现异常
		for (String key : attrMap.keySet()) {
			Object value = attrMap.get(key);
			obj.set(key, value);
		}
		Persistable persistable = obj.apply();
		return persistable;
	}
	
	public Persistable updatePersistable(Persistable persistable, boolean isOOTBValidate) throws WTException{
		if (isOOTBValidate) {
			persistable = PersistenceHelper.manager.modify(persistable);
		} else {
			PersistenceServerHelper.manager.update(persistable);
		}
		persistable = PersistenceHelper.manager.refresh(persistable);
		return persistable;
	}
}
